/**
 * Copyright(c) by JNet Smartware Group.
 * All rights reserved. Not distribution or redistribution without
 * any permission of JNet Smartware Group.
 * 
 * @author thuc
 * 2010/04/12
 * Program: SWTAuthorityEntry.java
 * 
 */
package vn.smartware.co.client.admin;

import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wb.swt.SWTResourceManager;

import vn.smartware.co.commons.Const;
import vn.smartware.co.commons.SWTUtils;
import vn.smartware.co.framework.bean.UserDTO;
import vn.smartware.co.framework.bean.ProgramDTO;
import vn.smartware.co.framework.common.BaseConstant;
import vn.smartware.co.framework.exception.ClientException;
import vn.smartware.co.framework.exception.FatalException;
import vn.smartware.co.framework.exception.ServerException;
import vn.smartware.co.framework.exception.SessionTimeOutException;
import vn.smartware.co.framework.form.BaseForm;
import vn.smartware.co.framework.plugin.LangResources;
import vn.smartware.co.framework.swt.base.JNetComposite;
import vn.smartware.co.framework.utils.MsgBoxUtils;
import vn.smartware.co.java.net.commons.SortUtil;
import vn.smartware.co.java.net.commons.Utils;

/**
 * SWTAuthorityEntry
 * @author thuctt
 */
public class SWTAuthorityEntry extends JNetComposite {

	private static Log log = LogFactory.getLog(SWTAuthorityEntry.class);

	private Button btnRemoveAll;

	private Button btnRemoveOne;

	private Button btnSelectOne;

	private Button btnSelectAll;

	private Table tblAssigned;

	private CLabel clblMessage;

	private Group grp;

	private Combo cmbUsers;

	private Button btnSave;

	private Button btnClear;

	private Table tblAvailable;

	private Button btnSelect;

	private Button btnClose;

	private static final int TBL_ROW_COUNT = 21;

	private ArrayList availablePrgs = new ArrayList();
	
	private ArrayList assignedPrgs = new ArrayList();
	
	private ArrayList allPrgs = new ArrayList();
	
	private ArrayList users = new ArrayList();
	
	private String userId = "";
	
	private static final int ALL = 0;
	
	private static final int ONE = 1;

	/**
	 * Constructor.
	 * 
	 * @param parent
	 * @param style
	 * @param prgName
	 */
	public SWTAuthorityEntry(Composite parent, int style, String prgName) {
		super(parent, style, prgName);
	}
	
	/**
	 * init data to display
	 * @throws FatalException
	 */
	protected boolean loadData() throws FatalException {
		BaseForm form = new BaseForm();
		form.setActionForm("baseForm");
		form.setActionMethod("getUsers");
		form = (BaseForm)execute(form);
		if (form.getUserList().isEmpty()){
			return false;
		}
		users = form.getUserList();
		String[] items = new String[users.size()];
		for (int i = 0; i < users.size(); i++) {
			UserDTO user = (UserDTO)users.get(i);
			String name = user.getName();
			if (Utils.isNullEmpty(name)){
				name = user.getUserName();
			}
			items[i] = user.getUserId() + Const.COMBO_SEPERATE + name;
		}
		cmbUsers.setItems(items);
		
		form.setActionMethod("getPrograms");
		form = (BaseForm)execute(form);
		if (form.getPrgList().isEmpty()){
			return false;
		}
		tblAvailable.setData(form.getPrgList());
		return true;
	}

	/**
	 * init controls
	 */
	protected void initialize() {

		final CLabel lblUser = new CLabel(this, SWT.CENTER | SWT.BORDER);
		lblUser.setBounds(55, 43, 100, 22);
		lblUser.setFont(BaseConstant.FONT_BASE_LABEL_NAME);
		lblUser.setText(LangResources.getText("SWTAuthorityEntry.lblUser"));
		
		btnSelect = new Button(this, SWT.NONE);
		btnSelect.setText(LangResources.getText("btnSelect"));
		btnSelect.setBounds(650, 43, 100, 23);
		btnSelect.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnSelect.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnSelect.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				searchAction();
			}
		});
		
		final Label line1 = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		line1.setBounds(0, 90, 812, 15);
		line1.setBackground(BaseConstant.COLOR_BGR_BASE);
		
		cmbUsers = new Combo(this, SWT.READ_ONLY);
		cmbUsers.setBounds(173, 42, 300, 24);
		cmbUsers.setTextLimit(200);
		cmbUsers.setFont(BaseConstant.FONT_BASE_LABEL);
		
		grp = new Group(this, SWT.NONE);
		grp.setBounds(10, 104, 790, 514);
		grp.setBackground(BaseConstant.COLOR_BGR_BASE);

		final Label lblTableAvailable = new Label(grp, SWT.LEFT);
		lblTableAvailable.setBounds(10, 30, 160, 18);
		lblTableAvailable.setFont(BaseConstant.FONT_BASE_LABEL);
		lblTableAvailable.setBackground(BaseConstant.COLOR_BGR_BASE);
		lblTableAvailable.setText(LangResources.getText("SWTAuthorityEntry.lblTableAvailable"));

		tblAvailable = new Table(grp, SWT.FULL_SELECTION | SWT.BORDER | SWT.CHECK);
		tblAvailable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				if (e.detail == SWT.CHECK){
					TableItem item = (TableItem)e.item;
					if (Utils.isNullEmpty(item.getData())){
						item.setChecked(false);
						return;
					}
					tblAvailable.setSelection(item);
				}
			}
		});
		tblAvailable.setBounds(10, 54,360, 436);
		tblAvailable.setLinesVisible(true);
		tblAvailable.setHeaderVisible(true);
		tblAvailable.setFont(BaseConstant.FONT_BASE_LABEL);
		tblAvailable.setData(BaseConstant.TABLE_ROW_COUNT, Integer.toString(TBL_ROW_COUNT));

		final TableColumn tcolCheck = new TableColumn(tblAvailable, SWT.NONE);
		tcolCheck.setAlignment(SWT.CENTER);
		tcolCheck.setWidth(30);

		final TableColumn tcolID = new TableColumn(tblAvailable, SWT.NONE);
		tcolID.setAlignment(SWT.RIGHT);
		tcolID.setWidth(45);
		tcolID.setText(LangResources.getText("SWTAuthorityEntry.tcolID"));
		
		final TableColumn tcolVnName = new TableColumn(tblAvailable, SWT.NONE);
		tcolVnName.setWidth(140);
		tcolVnName.setText(LangResources.getText("SWTAuthorityEntry.tcolVnName"));
		
		final TableColumn tcolEnName = new TableColumn(tblAvailable, SWT.NONE);
		tcolEnName.setWidth(140);
		tcolEnName.setText(LangResources.getText("SWTAuthorityEntry.tcolEnName"));
		
		btnSelectAll = new Button(grp, SWT.NONE);
		btnSelectAll.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				selectItems(ALL);
			}
		});
		btnSelectAll.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnSelectAll.setBounds(375, 175, 40, 23);
		btnSelectAll.setText(">>");
		
		btnSelectOne = new Button(grp, SWT.NONE);
		btnSelectOne.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				selectItems(ONE);
			}
		});
		btnSelectOne.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnSelectOne.setBounds(375, 204, 40, 23);
		btnSelectOne.setText(">");
		
		btnRemoveOne = new Button(grp, SWT.NONE);
		btnRemoveOne.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				removeItems(ONE);
			}
		});
		btnRemoveOne.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnRemoveOne.setBounds(375, 233, 40, 23);
		btnRemoveOne.setText("<");
		
		btnRemoveAll = new Button(grp, SWT.NONE);
		btnRemoveAll.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent arg0) {
				removeItems(ALL);
			}
		});
		btnRemoveAll.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnRemoveAll.setBounds(375, 262, 40, 23);
		btnRemoveAll.setText("<<");

		final Label lblTableAssigned = new Label(grp, SWT.LEFT);
		lblTableAssigned.setBounds(420, 30, 160, 18);
		lblTableAssigned.setFont(BaseConstant.FONT_BASE_LABEL);
		lblTableAssigned.setBackground(BaseConstant.COLOR_BGR_BASE);
		lblTableAssigned.setText(LangResources.getText("SWTAuthorityEntry.lblTableAssigned"));
		
		tblAssigned = new Table(grp, SWT.FULL_SELECTION | SWT.BORDER | SWT.CHECK);
		tblAssigned.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				if (e.detail == SWT.CHECK){
					TableItem item = (TableItem)e.item;
					if (Utils.isNullEmpty(item.getData())){
						item.setChecked(false);
						return;
					}
					tblAssigned.setSelection(item);
				}
			}
		});
		tblAssigned.setBounds(420, 54,360, 436);
		tblAssigned.setFont(BaseConstant.FONT_BASE_LABEL);
		tblAssigned.setLinesVisible(true);
		tblAssigned.setHeaderVisible(true);
		tblAssigned.setData(BaseConstant.TABLE_ROW_COUNT, Integer.toString(TBL_ROW_COUNT));
		
		final TableColumn tcolCheck1 = new TableColumn(tblAssigned, SWT.NONE);
		tcolCheck1.setAlignment(SWT.CENTER);
		tcolCheck1.setWidth(30);
		
		final TableColumn tcolID1 = new TableColumn(tblAssigned, SWT.NONE);
		tcolID1.setAlignment(SWT.RIGHT);
		tcolID1.setWidth(45);
		tcolID1.setText(LangResources.getText("SWTAuthorityEntry.tcolID"));
		
		final TableColumn tcolVnName1 = new TableColumn(tblAssigned, SWT.NONE);
		tcolVnName1.setWidth(140);
		tcolVnName1.setText(LangResources.getText("SWTAuthorityEntry.tcolVnName"));
		
		final TableColumn tcolEnName1 = new TableColumn(tblAssigned, SWT.NONE);
		tcolEnName1.setWidth(140);
		tcolEnName1.setText(LangResources.getText("SWTAuthorityEntry.tcolEnName"));
		
		final Label line2 = new Label(this, SWT.HORIZONTAL | SWT.SEPARATOR);
		line2.setBounds(0, 624, 812, 15);
		line2.setBackground(BaseConstant.COLOR_BGR_BASE);

		clblMessage = new CLabel(this, SWT.RIGHT | SWT.SHADOW_IN | SWT.BORDER);
		clblMessage.setBounds(10, 643, 250, 25);
		clblMessage.setForeground(BaseConstant.COLOR_LINK_LABEL);
		clblMessage.setFont(BaseConstant.FONT_BOLD_LABEL);
		clblMessage.setBackground(BaseConstant.COLOR_BGR_LABEL);
		clblMessage.setAlignment(SWT.CENTER);
		
		btnSave = new Button(this, SWT.NONE);
		btnSave.setBounds(485, 645, 100, 23);
		btnSave.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnSave.setText(LangResources.getText("btnSave"));
		btnSave.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnSave.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				saveAction();
			}
		});

		btnClear = new Button(this, SWT.NONE);
		btnClear.setBounds(591, 645, 100, 23);
		btnClear.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnClear.setText(LangResources.getText("btnClear"));
		btnClear.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnClear.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				clearAction();
			}
		});

		btnClose = new Button(this, SWT.NONE);
		btnClose.setBounds(697, 645, 100, 23);
		btnClose.setFont(BaseConstant.FONT_BASE_BUTTON);
		btnClose.setText(LangResources.getText("btnClose"));
		btnClose.setCursor(SWTResourceManager.getCursor(SWT.CURSOR_HAND));
		btnClose.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (!closeAction()){
					btnClose.setFocus();
				}
			}
		});
		
		this.getShell().setDefaultButton(btnSelect);
	}

	/**
	 * clearAction
	 */
	protected void clearAction() {
		
		ArrayList tmp = (ArrayList)tblAvailable.getData();
		allPrgs = (ArrayList)tmp.clone();
		assignedPrgs.clear();
		userId = "";
		//
		Control[] controls = new Control[]{
				btnSelect,
				cmbUsers
		};
		SWTUtils.OperatorUI.setEnableAll(controls, true);
		SWTUtils.OperatorUI.clearAll(grp.getChildren());
		displayTable(tblAvailable, allPrgs);
		SWTUtils.OperatorUI.setEnableAll(grp.getChildren(), false);
		btnSave.setEnabled(false);
		cmbUsers.select(0);
	}

	/**
	 * display table program
	 * @param list
	 */
	private void displayTable(Table table, ArrayList list) {

		table.removeAll();
		SortUtil.sort(list, new String[]{"prgId"}, SortUtil.ASC);
		int rowcount = TBL_ROW_COUNT;
		if (list.size() >= rowcount){
			rowcount = list.size() + 2;
		}
		for (int i = 0; i < rowcount; i++) {
			TableItem tblItem = new TableItem(table, SWT.NONE);
			
			if (i < list.size()){
				ProgramDTO prg = (ProgramDTO)list.get(i);
				
				String[] items = new String[table.getColumnCount()];
				int idx = 0;
				items[idx++] = "";
				items[idx++] = Integer.toString(prg.getPrgId());
				items[idx++] = prg.getVnName();
				items[idx++] = prg.getEnName();
				
				tblItem.setText(items);
				tblItem.setData(prg);
			}
			
			if (i%2 == 0){
				tblItem.setBackground(BaseConstant.COLOR_TABLE_ROW_EVEN);
			}
		}
	}

	/**
	 * saveAction
	 */
	protected void saveAction() {
		
		try {
			if (assignedPrgs.isEmpty()){
				MsgBoxUtils.warningMsgBox("warning.NO_DATA_SAVE");
				btnSave.setFocus();
				return;
			}
			
			//lock screen
			lockScreen(true);
			
			BaseForm form = new BaseForm();
			form.setActionForm("baseForm");
			form.setActionMethod("saveAuthProgramsAction");
			
			form.setPrgList(assignedPrgs);
			form.setUserID(this.userId);
			form = (BaseForm)execute(form);
			
			clearAction();
			
			MsgBoxUtils.setStatusLabelMessage(clblMessage, "info.SAVE_SUCCESSFUL");
		
		} catch (SessionTimeOutException e) {
			log.warn("SessionTimeOutException.", e);
			
		} catch (ServerException e) {
			log.error("ServerException.", e);
			fatalErrorMsgBox();
		} catch (FatalException e) {
			log.error("FatalException.", e);
			fatalErrorMsgBox();
		} finally {
			//unlock screen
			lockScreen(false);
		}
	}

	/**
	 * display action
	 */
	protected void searchAction() {
		
		try {
			userId = SWTUtils.ComboProcess.getSelectingValue(cmbUsers);
			if (!chkUserLocked()){
				int answer = MsgBoxUtils.questionMsgBox("question.USER_ACCOUNT_LOCKED", 
						new Object[]{SWTUtils.ComboProcess.getSelectingLabel(cmbUsers)});
				if (answer == SWT.NO){
					cmbUsers.setFocus();
					return;
				}
			}
			//get programs that current login user has permission
			BaseForm form = new BaseForm();
			form.setActionForm("baseForm");
			form.setActionMethod("getAuthPrograms");
			form.setUserID(this.userId);
			form = (BaseForm)execute(form);
			
			assignedPrgs = form.getPrgList();
			ArrayList tmp = (ArrayList)allPrgs.clone();
			for (int i = 0; i < assignedPrgs.size(); i++) {
				ProgramDTO assignedprg = (ProgramDTO)assignedPrgs.get(i);
				for (int j = 0; j < tmp.size(); j++) {
					ProgramDTO prg = (ProgramDTO)tmp.get(j);
					if (prg.getPrgId() == assignedprg.getPrgId()){
						tmp.remove(j);
						break;
					}
				}
			}
			availablePrgs = tmp;
			//display table
			displayTable(tblAvailable, availablePrgs);
			displayTable(tblAssigned, assignedPrgs);
			//
			Control[] controls = new Control[]{
					btnSelect,
					cmbUsers
			};
			SWTUtils.OperatorUI.setEnableAll(controls, false);
			SWTUtils.OperatorUI.setEnableAll(grp.getChildren(), true);
			btnSave.setEnabled(true);
			
			displayTable(tblAssigned, this.assignedPrgs);
			tblAvailable.setSelection(0);
			tblAvailable.setFocus();
			
		} catch (SessionTimeOutException e) {
			log.error("saveAction SessionTimeOutException.", e);
			
		} catch (ServerException e) {
			log.error("ServerException.", e);
			fatalErrorMsgBox();
			
		} catch (FatalException e) {
			log.error("FatalException.", e);
			fatalErrorMsgBox();
		}
	}
	
	/**
	 * check user if locked
	 * @return boolean
	 */
	private boolean chkUserLocked() {
		
		for (int i = 0; i < users.size(); i++) {
			UserDTO user = (UserDTO)users.get(i);
			if (Integer.toString(user.getUserId()).equals(this.userId)
					&& !Utils.isNullEmpty(user.getLockoutDate())){
				
				return false;
			}
		}
		return true;
	}

	/**
	 * remove items
	 * @param type
	 */
	@SuppressWarnings("unchecked")
	private void removeItems(int type) {

		try {
			switch (type) {
			case ONE:
				TableItem[] tblItems = tblAssigned.getItems();
				boolean checkFlg = false;
				for (int i = 0; i < tblItems.length; i++) {
					TableItem item = tblItems[i];
					if (item.getChecked()){
						availablePrgs.add(item.getData());
						assignedPrgs.remove(item.getData());
						checkFlg = true;
					}
				}
				if (!checkFlg){
					MsgBoxUtils.errorMsgBox("errors.NOT_SELECTED_RECORD");
					tblAssigned.setFocus();
					return;
				}
				//
				displayTable(tblAvailable, availablePrgs);
				displayTable(tblAssigned, assignedPrgs);
				//
				if (assignedPrgs.isEmpty()){
					//
					tblAvailable.setSelection(0);
					tblAvailable.setFocus();
					//
					btnRemoveOne.setEnabled(false);
					btnRemoveAll.setEnabled(false);
					//
					btnSelectOne.setEnabled(true);
					btnSelectAll.setEnabled(true);
					return;
				}
				//
				tblAssigned.setSelection(0);
				tblAssigned.setFocus();
				//
				btnSelectOne.setEnabled(true);
				btnSelectAll.setEnabled(true);
				break;
				
			case ALL:
				availablePrgs.addAll(assignedPrgs);
				assignedPrgs.clear();
				//sort list
				SortUtil.sort(availablePrgs, new String[]{"prgId"}, SortUtil.ASC);
				SortUtil.sort(assignedPrgs, new String[]{"prgId"}, SortUtil.ASC);
				//
				displayTable(tblAvailable, availablePrgs);
				displayTable(tblAssigned, assignedPrgs);
				//
				tblAvailable.setSelection(0);
				tblAvailable.setFocus();
				//
				btnRemoveOne.setEnabled(false);
				btnRemoveAll.setEnabled(false);
				//
				btnSelectOne.setEnabled(true);
				btnSelectAll.setEnabled(true);
				break;

			default:
				break;
			}
			
		} catch (ClientException e) {
			log.error("ClientException.", e);
			fatalErrorMsgBox();
		}
	}
	
	/**
	 * select items
	 * @param type
	 */
	@SuppressWarnings("unchecked")
	private void selectItems(int type) {

		try {
			switch (type) {
			case ONE:
				TableItem[] tblItems = tblAvailable.getItems();
				boolean checkFlg = false;
				for (int i = 0; i < tblItems.length; i++) {
					TableItem item = tblItems[i];
					if (item.getChecked()){
						assignedPrgs.add(item.getData());
						availablePrgs.remove(item.getData());
						checkFlg = true;
					}
				}
				if (!checkFlg){
					MsgBoxUtils.errorMsgBox("errors.NOT_SELECTED_RECORD");
					tblAvailable.setFocus();
					return;
				}
				//
				displayTable(tblAvailable, availablePrgs);
				displayTable(tblAssigned, assignedPrgs);
				//
				if (availablePrgs.isEmpty()){
					//
					tblAssigned.setSelection(0);
					tblAssigned.setFocus();
					//
					btnSelect.setEnabled(false);
					btnSelectAll.setEnabled(false);
					//
					btnRemoveOne.setEnabled(true);
					btnRemoveAll.setEnabled(true);
					return;
				}
				//
				tblAvailable.setSelection(0);
				tblAvailable.setFocus();
				//
				btnRemoveOne.setEnabled(true);
				btnRemoveAll.setEnabled(true);
				break;
				
			case ALL:
				assignedPrgs.addAll(availablePrgs);
				availablePrgs.clear();
				//sort list
				SortUtil.sort(availablePrgs, new String[]{"prgId"}, SortUtil.ASC);
				SortUtil.sort(assignedPrgs, new String[]{"prgId"}, SortUtil.ASC);
				//
				displayTable(tblAvailable, availablePrgs);
				displayTable(tblAssigned, assignedPrgs);
				//
				tblAssigned.setSelection(0);
				tblAssigned.setFocus();
				//
				btnSelectOne.setEnabled(false);
				btnSelectAll.setEnabled(false);
				//
				btnRemoveOne.setEnabled(true);
				btnRemoveAll.setEnabled(true);
				break;

			default:
				break;
			}
			
		} catch (ClientException e) {
			log.error("ClientException.", e);
			fatalErrorMsgBox();
		}
	}

	
	/**
	 * lockScreen
	 * @param flg 
	 */
	protected void lockScreen(boolean flg) {
		
		SWTUtils.OperatorUI.setEnableAll(this.getChildren(), !flg);
	}
}